use std::{str::FromStr, sync::Arc};

use async_trait::async_trait;

use crate::base::Task;

mod sea_orm_persistence;
pub use sea_orm_persistence::SeaOrmTaskPersistence;


#[derive(thiserror::Error, Debug)]
pub enum PersistenceError {
    #[error("Failed to save task: {0}")]
    SaveError(String),
    #[error("Failed to remove task: {0}")]
    RemoveError(String),
    #[error("Failed to update task status: {0}")]
    UpdateError(String),
    #[error("Task not found: {0}")]
    NotFound(String),
}

#[async_trait]
pub trait TaskPersistence {
    async fn save_task(&self, task_id: &str, task: &Arc<Box<dyn Task>>, status: TaskStatus) -> Result<(), PersistenceError>;
    async fn remove_task(&self, task_id: &str) -> Result<(), PersistenceError>;
    async fn update_task_status(&self, task_id: &str, status: TaskStatus) -> Result<(), PersistenceError>;
    async fn get_all_tasks(&self) -> Result<Vec<(String, Arc<Box<dyn Task>>, TaskStatus)>, PersistenceError>;
}

#[derive(Debug, Clone)]
pub enum TaskStatus {
    Pending,
    Running,
    Completed,
    Failed,
}

impl FromStr for TaskStatus {
    type Err = String;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s {
            "Pending" => Ok(TaskStatus::Pending),
            "Running" => Ok(TaskStatus::Running),
            "Completed" => Ok(TaskStatus::Completed),
            "Failed" => Ok(TaskStatus::Failed),
            _ => Err(format!("Unknown task status: {}", s)),
        }
    }
}
